test(cli): mask comments in the nightly-tier readers of this package's own source, and derive the pins that bound a spelling - #18924
Merged
os-support-ai merged 2 commits intoSep 18, 2026
Conversation
…s own source WIP: the twelve nightly-tier test files that read `packages/cli`'s own source text now read it through the shared `maskComments`, and three byte-exact pins are rewritten to bind a derived property instead of a spelling. Claude-Session: https://claude.ai/code/session_01DvvamiacK328idtBYJBxV3 Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DvvamiacK328idtBYJBxV3 Co-authored-by: Claude <noreply@anthropic.com>
Contributor
📓 Docs Drift CheckNothing in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 0 changed package(s)), so this run has no opinion about the docs. What this run could not see
Coarse fallback — 0 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): |
This was referenced Sep 18, 2026
os-support-ai
marked this pull request as ready for review
September 18, 2026 06:45
os-support-ai
enabled auto-merge
September 18, 2026 06:46
os-support-ai
deleted the
claude/issue-18520-nightly-pin-source-readers
branch
September 18, 2026 07:03
akarma-synetal
pushed a commit
to akarma-synetal/framework
that referenced
this pull request
Sep 28, 2026
… so an honest new exit cannot red `main` at night (objectstack-ai#18966) Fixes objectstack-ai#18894 Clause-②: no ## What this changes `packages/cli/test/build-json-failure-warnings.e2e.test.ts` and `packages/cli/test/build-json-failure-conversions.e2e.test.ts` each froze three integers read off `packages/cli/src/commands/compile.ts` — 11 payload literals, 10 `success: false`, 1 `success: true`. **All six were correct**, and that is the defect: the *shape*, not a stale number. One honest new exit — the very thing these two files exist to enforce — turns all six red, and because both files are nightly-tier by NAME they turn red only at night, hours after the PR that did it has merged. That is objectstack-ai#18848's `priority:p1` pre-staged on `compile.ts`. Ported from the shape PR objectstack-ai#18880 landed on the sibling `validate-json-failure-*` pair: - the count is **derived** — `toHaveLength(callSites.length)` against a word-boundary `emitJson` call-site match over **the same masked source** the payload extractor reads; - the old integer is demoted to a **floor**, `toBeGreaterThanOrEqual(10)`, which rots only in the exits-are-REMOVED direction; - one **partition** assertion (`success: true` ×1, `success: false` = `literals.length - 1`) replaces the two frozen counts. ⛔ No production file is touched. The diff is those two test files and nothing else — `compile.ts` is card objectstack-ai#18431's carrier (branch `ccdc9f5389`) and is left alone. ## Premises, re-measured on `origin/main` before a line was written Re-derived with the tests' OWN extractor against the masked `compile.ts` at `f112a740bd` (`origin/main` at branch point), ⛔ not inherited from the card: ``` payload literals 11 the pins' 11 was correct success: false 10 correct success: true 1 correct /\bemitJson\s*\(/g 11 symmetric with the extractor ``` **Collection, re-measured in this worktree** (`vitest list --filesOnly`, `packages/cli`): `OS_TEST_TIERS` unset ⇒ 267 files, **0** of these two among them, lit control `artifact-packages.test.ts` present; `=nightly` ⇒ 68 files, **both** present, lit control absent. Both files sit in the `integration` project (`--project unit` collects 0 of them). ##⚠️ The trap this card names — the verdict key, MEASURED not copied **`compile.ts` spells its verdict key `success:`. `validate.ts` spells it `valid:`.** Measured over the 11 masked payload literals of `compile.ts`: | needle | count | |:--|--:| | `success: false` | 10 | | `success: true` | 1 | | `valid: false` | **0** | | `valid: true` | **0** | A verbatim port of objectstack-ai#18880's two partition lines would have asserted over an **empty population**. The lines here read `success:`, and the reading is recorded in the code comment beside them so the next author does not have to re-derive it. ## The symmetry the derived form needs — every `emitJson` occurrence enumerated The looser `/\bemitJson\s*\(/g` can only be trusted equal to the extractor's `await emitJson(` needle if nothing else in the file matches it. Enumerated with left context on `compile.ts`, **13 raw occurrences**: | where | reading | |:--|:--| | `:43` | `emitJson,` — an **import** from `../utils/format.js`. No paren ⇒ matches neither side. | | `:104`, `:694` | prose inside comments — the shared `maskComments` blanks both (objectstack-ai#18520, applied to these two files by objectstack-ai#18924) | | the other 10 | `await emitJson(` call sites, plus the multi-line ones ⇒ 11 payload literals | ⭐ `emitJson` is **IMPORTED here, never declared** — there is no `function emitJson(` in `compile.ts` (grep: zero hits for `function emitJson` / `const emitJson`), so the looser pattern cannot over-count and red the pin by construction. Raw and masked agree: 11 literals, 11 call sites, both ways. That agreement is a **reading, not a law**, and the derived equality is exactly where a future file that broke it would report. ## The floor's anchor — 10, and why not 11 objectstack-ai#18880 chose "the population the governing ruling was made over", not today's count. The equivalent anchor here is the commit that landed each file's ruling, read out of git: | file | ruling | landed by | count pinned that day | |:--|:--|:--|--:| | `build-json-failure-warnings.e2e.test.ts` | maintainer, 2026-08-25, option 1 (objectstack-ai#11772) | `d114d5e140` (objectstack-ai#12079) | `toHaveLength(10)` — 9 failure + 1 success | | `build-json-failure-conversions.e2e.test.ts` | the same 2026-08-25 ruling applied to `conversions` (objectstack-ai#12125) | `79cf692b0e` (objectstack-ai#12285) | `toHaveLength(10)` — "all nine of its failure exits" + 1 | Control for the anchor rule: the sibling `validate-json-failure-warnings.e2e.test.ts` was created at `33e81a5fe0` (objectstack-ai#12130) pinning `toHaveLength(6)`, and objectstack-ai#18880's floor is `6`. Same rule, same arithmetic. ⇒ **the floor here is 10.** Today's eleventh exit is ADR-0130 D4's per-package author-time rule leg (objectstack-ai#14439), which arrived *after* the ruling — exactly what a derived count absorbs and a frozen one trips over. ## Ablation battery — every leg's mutation proven on disk, every restore proven by hash Harness: a bash trap on EXIT, INT and TERM whose handler is the restore function, absolute paths, restore is `git checkout HEAD -- PATH` (never a bare `git checkout --`), verified by comparing `git hash-object` against the HEAD blob hash **and** by `git diff HEAD` being empty. Each leg prints the extractor's counts BEFORE and AFTER the mutation and a marker grep, so a no-op leg is refused rather than read as green. All runs `OS_TEST_TIERS=nightly`, exit codes captured before any pipe. No rebuild is needed or done: both files read `compile.ts` from disk and the CLI is loaded from `src/` through `bin/run-dev.js`, as each file's own header states. | leg | mutation to `compile.ts` | measured on disk after | THIS branch | the frozen `11/10/1` | |:--|:--|:--|:--|:--| | 0 control | none | literals 11 · sites 11 | **GREEN** 7/7 | — | | A | honest 12th exit carrying **both** keys | literals 12 · sites 12 | **GREEN** 7/7 | **RED** — `expected [ …(12) ] to have a length of 11` (both files) | | B | 12th exit **missing** both keys | literals 12 · sites 12 | **RED** — `an os build --json exit publishes no warnings` / `no conversions` | — | | C | 12th call site spelled **without `await`** | literals 11 · sites **12** | **RED** — `an emitJson( call site the payload extractor could not read: expected [ …(11) ] to have a length of 12` | **GREEN** 7/7 | | D | two exits deleted (truncation) | literals 9 · sites 9 | **RED** — `publishes fewer exits than the ruling above was made over: expected 9 to be greater than or equal to 10` | — | ⭐ **Leg C is the one that decides it.** A twelfth call site the payload extractor cannot read leaves the frozen integer **green** and reddens the derived equality. The frozen form is not a parallel option — it is strictly weaker. Leg A is the mirror: the honest exit this contract exists to welcome now stays green instead of reddening `main` at 20:44Z. The "old" arms of A and C ran the pre-change files restored worktree-only with `git restore --source=f112a740bd -- PATH`, hashes printed and matched against the BASE blobs, then reset with `git checkout HEAD -- PATH`. ## `skip-changeset`, by measurement with controls both ways `packages/cli` `files[]` is `["dist","README.md","CHANGELOG.md"]`; `tsconfig.build.json` has `rootDir: "src"`, `include: ["src"]` and an `exclude` that drops every `*.test.ts`. Measured against the freshly built `packages/cli/dist`: | probe | direction | hits in `dist/` | |:--|:--|--:| | `an emitJson( call site the payload extractor could not read` | new, this diff | **0** | | `publishes fewer exits than the ruling above was made over` | new, this diff | **0** | | `ABLATION` | new, this diff | **0** | | `access matrix drift` | positive control, lives in `src/commands/compile.ts` | 1 | | `warningsSoFar` | positive control | 2 | | `runtime bundle failed` | positive control | 1 | | `build-json-failure` |⚠️ 1 hit — `dist/commands/compile.js:621`, a **comment** compiled from `src/commands/compile.ts:698` that names the test file. Not this diff's content; `compile.ts` is untouched. | 1 | The positive controls prove the grep was reading `dist`. Nothing this diff adds reaches any published path from any released package ⇒ `skip-changeset`, label applied on this PR. ##⚠️ The adjacent axis — a POSITION, not a silent widening Comment 5726117707 on the card asked for a judgement on the byte-exact multi-line spread ORDER pin, and warned its own probe was narrow. **Re-derived here with a different predicate** (`expect(SRC)` / `SRC.match` / `SRC.indexOf` across all four files), which finds MORE than the seat's word probe did — including one in `validate-json-failure-conversions.e2e.test.ts`, where the seat's probe scored 0 and recorded it as **未判**: | file | line | what it binds byte-exactly | |:--|--:|:--| | `build-json-failure-warnings.e2e.test.ts` | `:536` `:537` | `const warningsSoFar = () => [` , and the 4-member spread ORDER | | `build-json-failure-conversions.e2e.test.ts` | `:450` | sink declaration + blank line + `try {` adjacency | | `validate-json-failure-warnings.e2e.test.ts` | `:571` `:572` | the same two, 5 members | | `validate-json-failure-conversions.e2e.test.ts` | `:486` | the same adjacency ⇐ **the seat's 0 was 未判, not absent** | **Judgement: named, measured, and left to the seat — deliberately NOT done in this PR.** Against the lane's standing three-rung ruling (claim 5725386686 on objectstack-ai#18520): - **Rung 1** — 「⛔ nightly-only 的 pin 永不绑一个逐 PR 兄弟已经绑着的字节精确拼写。」 Its precondition is measured **FALSE**. Repo-wide, the only other reader of those four list identifiers is `build-json-advisory-parity.e2e.test.ts`, which is itself **nightly-tier** and compares with `new Set(...)` — order-blind by construction. No per-PR sibling binds this order behaviourally or textually. ⇒ rung 1 does not authorise deleting it. - **Rung 2** — 「⭐ nightly-only 的 pin 绑那条性质本身,从源码推导 —— 读出来的计数、分区、下限 —— ⛔ 永不绑一个写死的数。」 It governs frozen **numbers**. The order pin binds a *spelling*. ⇒ rung 2 does not reach it; this PR discharges rung 2 for the counts, which is this card. - **Rung 3** — 「⭐ 一个读原始源码文本的读者,要么能把代码和散文分开,要么就不该对位置/顺序下 断言。」 Already satisfied: PR objectstack-ai#18924 put the shared `maskComments` in place on both files. ⛔ Not re-added here. ⇒ Under the ruling **as written and as measured**, the order pin in these two files is currently compliant and needs no change. What is *not* settled is a rung-1 **extension**: may a nightly-only pin bind a byte-exact spelling when **no** per-PR sibling binds the property at all? That is a new question, not an application of the existing three rungs, and it sits identically on the `validate-json-failure-*` pair, **which has no carrier card**. Widening this PR to answer it would convert half a family under a rule nobody has made yet. Handed to the `domain:cli` seat as a finding with dedupe words. ## Verification Measured on `git rev-parse --short HEAD` = `0eb90c0a91`, in worktree `/home/user/objectstack-issue-18894`, branched from `origin/main` at `f112a740bd`. | what | how | result | |:--|:--|:--| | the two files, BEFORE the edit | `OS_TEST_TIERS=nightly … --project integration` on both files | **27 passed (27)** — the pins were correct, as the card said | | the two files, AFTER the edit | same | **27 passed (27)** | | `packages/cli` WHOLE, default tier | `pnpm --filter @objectstack/cli test` (bare `vitest run`, ⛔ no `--project`) | **267 files / 3485 tests passed** | | `packages/cli` WHOLE, nightly tier | `OS_TEST_TIERS=nightly pnpm --filter @objectstack/cli test` | **68 files / 695 tests passed** — the tier that actually collects these two files | | typecheck | `pnpm --filter @objectstack/cli typecheck` | exit 0 (incl. `check:test-typecheck`) | | dependency closure + package build | `pnpm --filter '@objectstack/cli^...' build` then `pnpm --filter @objectstack/cli build` | exit 0 both — required, several pins refuse at load without it | | gate families | `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack`, then `--ran` with exit codes | 47 derived, **46 run green**, **1 NOT MEASURED** | | whole-repo lint | `pnpm lint` (`eslint . --no-inline-config`), NOT narrowed | exit 0 | **NOT MEASURED (1)**: `pnpm check:dual-build-cjs-loads` exits **3** — `PREREQUISITE NOT MET — this gate reads built output, and some package has no dist/`. It needs a whole-repo `pnpm build`; this worktree built only the `@objectstack/cli` closure. ⛔ Recorded as NOT MEASURED, not as a pass and not as a red. CI's `Build Core` job builds the tree and measures it there. `dispatch-gates --ran` classified it from the recorded exit code rather than from a claim. Two derivation caveats stated rather than hidden: `dispatch-gates` printed a **STALE TREE** warning (`origin/main` moved 2 commits under this branch, touching `scripts/check-adr-0087-registration.mjs` and `scripts/check-single-claim-paths.mjs`); the command list was re-derived after `git fetch origin main` and came back **byte-identical**, so the 47 stands. And the tool's own footer is quoted rather than paraphrased: the 47 is not a complete account of CI — 51 artifact-roster families, 11 wide-population families, 13 pending-changeset families and 5 path-scheduled CI jobs are outside it by construction. ## Acceptance notes Noted, not filed — observations from the two files, none of them a reproducible defect, a contract violation, or a metadata-authoring trap: - The `describe` blocks in both files are still titled with their originating card numbers (`objectstack-ai#11772`, `objectstack-ai#12125`) while the assertions inside them now answer objectstack-ai#18894 too. Cosmetic; renaming a `describe` moves every `-t` filter that names it. Carrier: whoever next opens these files for a behavioural change. - `packages/cli/test/build-json-advisory-parity.e2e.test.ts` is nightly-tier and is the only other reader of the four advisory-list identifiers; its `new Set(...)` comparisons are deliberately order-blind, so the family has **no** order coverage in the per-PR tier at all. Recorded as the measurement behind the adjacent-axis position above, not as a defect. Carrier: the `domain:cli` seat, together with the rung-1 extension question. --- _Generated by [Claude Code](https://claude.ai/code/session_01DvvamiacK328idtBYJBxV3)_ Co-authored-by: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #18520
Clause-②: no
The nightly-tier test files under
packages/cli/test/that read this package's own sourceTEXT now read it through the shared mask (
scripts/js-comment-mask.mjs), and the pins thatbound a byte-exact SPELLING now bind a property derived from the source instead. Every file
was judged on its own; the table below gives the rung and the reason per file.
The population, re-derived — no number inherited
Predicate, stated: a file under
packages/cli/test/whose NAME puts it in a nightly tier(
scripts/nightly-tiers.mjs—*.e2e.test.*/*.live.test.*, and nothing else selects atier), which READS this package's own source text at test time, directly or through a helper
under
test/helpers/it imports. Evaluated over each file's local import closure, on MASKEDtext, so a read one module away still counts and a path named only in prose does not.
test/*.e2e.test.tscontainingreadFileSyncserve-port-readback,published-entry-stderr-nonblocking,run-dev-stderr-nonblockinggrep -rl readFileSync test/*.e2e.test.ts | xargs grep -l 'src/'⭐ 20 and 15 are not a contradiction — they are two predicates, and the delta is readable
both ways. Eight files are in the claim's 20 and not in mine, three are in mine and not in
its 20:
lint-eval-generator-load-envelopematchessrc/in a docblock sentenceand reads
/definitely/not/here.json. This is the false positive the dispatch predicted.src/, not ours —build-docs-step-count,build-multi-package-artifact,generate-skill,serve-publishes-bound-portcreatesrc/docsorsrc/skillsinside ascratch project and read
dist/objectstack.jsonback.scaffold-emission-policyreadspackages/create-objectstack'stemplate
package.json. JSON carries no comments, so no rung applies.bin/notsrc/—published-entry-stderr-nonblocking(already masked)and
run-dev-unbuilt-workspace(raw). Both read a hand-written published entry; the second isin this PR, the first was already correct.
config-miss-stdout-purityreadssrc/commandsthroughtest/helpers/config-miss-family.tsand never spellssrc/itself;invocation-loudnessandserve-host-fallback-baseDO spell../src/...but never read itas text — they
symlink/execFileit, so they are readers of a module, not of prose.Rung per file
build-json-failure-conversions.e2e.test.tssrc/commands/compile.tsindexOfORDER block (declAt/tryAt/loadAt/normalizeAt) is the #17633 shape verbatim — raw positions over a file whose docblocks nameawait loadConfig(. ⛔ The six frozen integers are card #18894's and are untouched here.build-json-failure-warnings.e2e.test.tssrc/commands/compile.tscloud-login-json-ndjson.e2e.test.tssrc/commands/cloud/login.tsemitJson(hits now partitions the call sites againstemitRecord's own brace-matched body: outside must be empty, inside must not be.login-json-ndjson.e2e.test.tssrc/commands/login.tslogin-json-noninteractive.e2e.test.tssrc/commands/login.tsrl.question(filter already binds a SHAPE (does the line carry the abort signal), not a spelling — rung 2 has nothing to convert.json-stdout-purity.e2e.test.tssrc/commands/**toHaveLength(10)demoted to a floor. The line above it already binds the SET against the map a sibling nightly file drives, so the integer was a second frozen copy of one fact. It stays as a floor because it is the only guard on the vacuum both sides share.config-miss-stdout-purity.e2e.test.tssrc/commands/**via helpertest/helpers/config-miss-family.ts, which this PR masks once for both consumers.test/helpers/config-miss-family.tssrc/commands/**json: Flags.boolean(beside autils/config.jsimport invents a direct member; a commented-outexport default class X extends Yinvents an alias.diff-usage-error-stream.e2e.test.tssrc/commands/**flags.jsonread — which is the print-ORDER failure that opened this card. ItstoBeGreaterThan(10)population control was already a floor.run-dev-unbuilt-workspace.e2e.test.tsbin/run-dev.jsexectakes the FIRST match, so a docblock recording the oldSTDERR_DRAIN_STALL_MSwould be read as the shim's bound. Its sibling over the other published entry already masks; this makes the pair consistent.serve-app-anchored-optional-import.e2e.test.tssrc/commands/serve.tsvalidate-json-failure-conversions.e2e.test.tssrc/commands/validate.tsvalidate-json-failure-warnings.e2e.test.tssrc/commands/validate.tsserve-port-readback·published-entry-stderr-nonblocking·run-dev-stderr-nonblockingRung 1 — where it applied, and where it did NOT
Rung 1 permits DELETING a nightly assertion when a per-PR sibling already binds the same
thing. I searched for a sibling for every byte-exact subject in this population and opened
the one I found:
serve-app-anchored-optional-importboundfunction importFromHost(specifier: string, hostRoot: string = servedAppRootOrCwd())— anargument LIST, the feat(cli):
objectstack dev --cert/--keyterminates TLS in the dev process, and the canonical origin follows the listener #17725 shape exactly.src/commands/serve-cluster-host-resolution.test.tsis queue-tier (its name carries no
.e2e, sonightly-tiers.mjsleaves it in the per-PR run)and binds that function's EXISTENCE, its module scope and its uniqueness. So this PR does not
re-pin any of that here; what it keeps, because the sibling does not bind it, is the DEFAULT —
read off the paren-matched parameter list.
anchorServedAppandservedAppRootOrCwdappear in no other test in the package. The login emitter contract(
emitRecord) appears in no queue-tier test at all. ForwarningsSoFar, the queue-tiertest/truncation-remainder-notices.test.tsbinds'warnings: warningsSoFar(),'incompile.ts— the CALL SITE, not the declaration and not the spread ORDER these files pin,and for
validate.tsit binds different payload keys entirely. Not the same thing, sonothing was deleted on its account.
serve-app-anchored-optional-importin detailFive
toContain/toMatchpins over whole statements ofserve.ts, in a file only the nightlytier collects. Each now binds what it was written for:
toContain('const { configPath: absolutePath, configExists } = anchorServedApp(args.config!);')anchorServedApp(call site (the declaration excluded by the samefunctionlookbehind the per-PR sibling uses), and its ARGUMENT isargs.config!. The destructured local names are deliberately no longer bound.not.toMatch(/const absolutePath = path\.resolve\(process\.cwd\(\), args\.config!\)/)path.resolve(process.cwd(), args.configwith whitespace tolerated. A negative pin on one exact spelling passes for every respelling of the defect.toContain('function importFromHost(specifier: string, hostRoot: string = servedAppRootOrCwd())')hostRootparameter's DEFAULT, read off the paren-matched parameter list. A third parameter or a renamedspecifierno longer reddens it.toContain('const hostRoot = servedAppRootOrCwd();')andtoContain('const root = hostRoot ?? servedAppRootOrCwd();')const/lethost-root binding: at least two exist, and none may be bound without resolving throughservedAppRootOrCwd().toMatch(/^function servedAppRootOrCwd\(\): string \{$/m)function servedAppRootOrCwd(, never indented, never aconst/let/var. The return-type annotation and the brace are not the defect.What the mask changed TODAY: nothing — and that is the measurement
Every converted reader was evaluated raw and masked over the same tree, and every verdict is
identical. Masking is therefore behaviour-preserving now and protective later — it did not
launder a stale pin green:
⛔
scripts/check-comment-mask-adoption.mjsis green before and after and its ledger isunchanged at 14 rows — because none of these twelve files ever carried a private stripper.
They carried NO masking at all, which is the blind spot the card names and the gate documents.
This PR adds no private stripper; every file imports the shared module.
Ablations
Each is a script with
traprestore onEXIT INT TERM, absolute paths, an on-disk occurrencecount proving the mutation landed, exit codes captured BEFORE any pipe, and a restore proven by
git hash-objectagainst the HEAD blob plus a cleangit statusfor both paths.without
OS_TEST_TIERS=nightlythe package collects none of these files, and it says soloudly. Recorded here because a run that measured nothing is the failure mode this card is
about. The numbers below are from the re-run with the switch set.
ABL-1 — the #17633 shape, reproduced and then shown fixed. A COMMENT is injected into
src/commands/info.tsbetweenasync run(and its firstflags.jsonread, namingprintHeader(. Behaviour is untouched; only prose moved.diff-usage-error-streamAssertionError: expected [ 'info.ts' ] to deeply equal []⭐ That failure line IS the card's first row: a docblock reporting an order change that never
happened.
ABL-2 —
serve.ts, both directions.const hostRoot = servedAppRootOrCwd();becomesprocess.cwd()a host root is bound without resolving through servedAppRootOrCwd(): expected [ Array(1) ] to deeply equal []— the new partition is not vacuousimportFromHost, same arguments, same behaviourexpected '…' to contain 'function importFromHost(specifier: st…'— #17725 verbatim, on a pin no pull request can seeABL-3 — the login emitter partition.
await emitJson(outsideemitRecordevery --json write in login.ts must go through emitRecord(): expected [ Array(1) ] to deeply equal []emitJson(payload, 0)All three restored cleanly:
git hash-objectmatches the HEAD blob for every mutated path andgit status --porcelainis empty for both paths in each script.Verification
OS_TEST_TIERSunset collects none of these files. Every red/green below isunder
OS_TEST_TIERS=nightly. Independently confirmed bypnpm check:tier-file-adoption:68 nightly-tier files on disk, owned by one package.
packages/clibuilt (pnpm --filter '@objectstack/cli...' build) so the pins that refuseat load on an absent
dist/index.jsactually run.--projectfilter — what CI runs:The 12 converted files were also run on their own under
OS_TEST_TIERS=nightlybefore thewhole runs: 12 files / 336 tests / exit 0.
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackand reconciled with--ran: 47 derived, 46 run green, 1 NOTMEASURED —
pnpm check:dual-build-cjs-loadsexits 3 (PREREQUISITE NOT MET: it reads builtoutput for packages outside this closure). ⛔ Recorded as NOT MEASURED, not as a pass and not
as a red.
pnpm lintover the whole repo, unnarrowed.node --stack-size=4000 eslint . --no-inline-configover the whole repository, exit 0.This is the unnarrowed run, so no narrowing has to be justified.
skip-changeset, by measurement with controls both waysThis PR's own diff (
git diff --name-only origin/main...HEAD) is 12 files, all underpackages/cli/test/.packages/cli'sfiles[]is["dist","README.md","CHANGELOG.md"]andtsconfig.build.jsonhasinclude: ["src"], sotest/reaches neither. Measured against thebuilt tree rather than argued:
bodySpan,splitParams,paramsOf(the three symbols this PR introduces):0 files in
dist, 0 inREADME.md.anchorServedApp(2 files),servedAppRootOrCwd(2),emitRecord(3)in
dist, so the grep over the published tree finds things and the zero above is a reading,not a dead search.
scripts/**path is touched, so the published surface did not have to be re-derived.Fences
build-json-failure-{warnings,conversions}are untouched; card[finding] two more nightly-only
emitJsonexit-count pins freeze 11/10/1 overcompile.ts— green today, one honest exit from rerunning the #18848 p1 #18894 owns that axis. Only rung 3 was applied in those two files.compile.ts's own comment that the survivors are "exactly the set the union could not see" overstates what it keeps #18779) was re-measured at the start: zero intersection with this population,and it has since merged as
031e5fbfa3. Itscompile.ts/validate.tsedits moved no countthese pins read (compile.ts still 11 payloads, validate.ts still 7), re-measured after the
merge. This PR touches none of its six test files.
content/docs/releases/and everypackages/*/CHANGELOG.mduntouched.Acceptance notes
src/commands/serve-cluster-host-resolution.test.tscarries a privatestripCommentsatline 151. It is a DECLARED row in
check-comment-mask-adoption.mjs's shrink-only ledger,measured there as agreeing with the shared mask byte for byte over 212 files, so it is
recorded debt rather than a finding, and converting it is that ledger's per-row work.
Noted, not filed.
validate-json-failure-{warnings,conversions}still pin a multi-line spread ORDER invalidate.tsbyte-exactly (...ruleAdvisories, ...docWarnings, ...), and the twobuild-json-failure-*files pin the same shape overcompile.ts. That is a rung-1/rung-2question on an axis this PR did not open, and for the
build-*pair it sits in the file thefence closes. Noted, not filed — the carrier is card [finding] two more nightly-only
emitJsonexit-count pins freeze 11/10/1 overcompile.ts— green today, one honest exit from rerunning the #18848 p1 #18894, which is already open over thosetwo files.
invocation-loudness.e2e.test.tsandserve-host-fallback-base.e2e.test.tsreach../src/...and are NOT source-text readers (they symlink and execute it). No rung applies;recorded so the next re-derivation does not re-open them. Noted, not filed.
Generated by Claude Code